package com.ksyun.campus.dataserver.services;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ksyun.campus.dataserver.domain.FileInfo;
import com.ksyun.campus.dataserver.domain.FileType;
import com.ksyun.campus.dataserver.domain.Result;
import com.ksyun.campus.dataserver.mapper.FileMapper;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Service
public class DataService {

    @Autowired
    private FileMapper fileMapper;

    public void write(byte[] data){
        //todo 写本地
        //todo 调用远程ds服务写接口，同步副本，以达到多副本数量要求
        //todo 选择策略，按照 az rack->zone 的方式选取，将三副本均分到不同的az下
        //todo 支持重试机制
        //todo 返回三副本位置
    }

    public Result write(String fileSystemName, String path, Integer offset, Integer length, MultipartFile file) {

        int lastSlashIndex = path.lastIndexOf('\\');
        String fileName = path.substring(lastSlashIndex + 1);
        Map<String, Object> result = new HashMap<>();

        try{
            if(fileName.contains(".")) //是文件
            {

                byte[] content = file.getBytes();

                if (offset == null) {
                    // 清除原文件内容并写入新数据
                    try (RandomAccessFile raf = new RandomAccessFile(path, "rw")) {
                        raf.setLength(0); // 清除文件内容
                        raf.write(content);
                    }
                } else {
                    try (RandomAccessFile raf = new RandomAccessFile(path, "rw")) {
                        raf.seek(offset);
                        raf.write(content);
                    }
                }


                result.put("message", "Write successful");
                result.put("locations", Arrays.asList("location1", "location2", "location3"));

                //写入数据库,先查看有无存在
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("file_path",path);
                wrapper.eq("file_name",fileName);
                FileInfo fileInfo1 = fileMapper.selectOne(wrapper);
                if(fileInfo1==null) //这个文件的记录还不存在
                {
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setFileName(fileName);
                    fileInfo.setFilePath(path);
                    fileInfo.setFileSize(file.getSize());
                    Long now = System.currentTimeMillis();
                    fileInfo.setCreateTime( now );
                    fileInfo.setUpdateTime(now);
                    fileInfo.setFolderType(FileType.File.getCode());
                    fileInfo.setFileSystemName(fileSystemName);
                    //还有三个副本的位置
                    fileMapper.insert(fileInfo);
                }else //已存在，更新
                {
                    FileInfo fileInfo = new FileInfo();
                    Long now = System.currentTimeMillis();
                    fileInfo.setUpdateTime(now);
                    fileInfo.setFileSize(file.getSize()+fileInfo1.getFileSize());
                    fileMapper.update(fileInfo,wrapper);
                }



            }else //是目录
            {
                File directory = new File(path);
                directory.mkdirs();

                //写入数据库,先查看有无存在
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("file_path",path);
                wrapper.eq("file_name",fileName);
                FileInfo fileInfo1 = fileMapper.selectOne(wrapper);
                if(fileInfo1==null) //这个文件的记录还不存在
                {
                    FileInfo fileInfo = new FileInfo();
                    fileInfo.setFileName(fileName);
                    fileInfo.setFilePath(path);
                    Long now = System.currentTimeMillis();
                    fileInfo.setCreateTime( now );
                    fileInfo.setUpdateTime(now);
                    fileInfo.setFolderType(FileType.Directory.getCode());
                    fileInfo.setFileSystemName(fileSystemName);
                    //还有三个副本的位置
                    fileMapper.insert(fileInfo);
                }else //已存在，更新
                {
                    FileInfo fileInfo = new FileInfo();
                    Long now = System.currentTimeMillis();
                    fileInfo.setUpdateTime(now);
                    fileMapper.update(fileInfo,wrapper);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();  // 打印异常栈
            return Result.fail("写文件失败了: "+path);
        }

        return Result.success("success", result);
    }

    public Result<byte[]> read(String fileSystemName, String path, Integer offset, Integer length) {
        int lastSlashIndex = path.lastIndexOf('\\');
        String fileName = path.substring(lastSlashIndex + 1);
        if(!fileName.contains("."))
        {
            return Result.fail("你传入的路径是文件夹!");
        }

        try {
            System.out.println("Received path: " + path);
            System.out.println("Received offset: " + offset);
            System.out.println("Received length: " + length);

            Path filePath = Paths.get(path);
            if (!Files.exists(filePath)) {
                return Result.fail("path不存在!");
            }

            byte[] content;

            try (RandomAccessFile raf = new RandomAccessFile(filePath.toFile(), "r")) {
                long fileLength = raf.length();

                // 如果 offset 超出文件大小，则返回空字节数组
                if (offset != null && offset >= fileLength) {
                    return Result.success("offset超出文件大小",new byte[0]);
                }

                // 如果未指定 offset 或 length，读取整个文件
                if (offset == null || length == null) {
                    content = Files.readAllBytes(filePath);
                } else {
                    // 调整 length 以确保不超过文件末尾
                    length = Math.min(length, (int) (fileLength - offset));

                    content = new byte[length];
                    raf.seek(offset);
                    raf.readFully(content);
                }
            }

            return Result.success("success",content);
        } catch (IOException e) {
            e.printStackTrace();  // 打印异常栈
            return Result.fail("读取文件失败!");
        }

    }


}
